package edu.uts.reekie.designer.execution.figures;

import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.List;

import org.eclipse.draw2d.*;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.*;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.handles.HandleBounds;
import org.eclipse.swt.graphics.*;

import edu.uts.reekie.designer.ImageHelper;
import edu.uts.reekie.designer.figures.AnchorFigure;
import edu.uts.reekie.designer.figures.FixedSizeFlowLayout;
import edu.uts.reekie.designer.figures.FixedSizeStackLayout;
import edu.uts.reekie.designer.figures.MultipleFigure;
import edu.uts.reekie.designer.figures.NameableFigure;

/*
 * 
 * 
 */
public class ViewComponentFigure 
		extends Figure 
		implements HandleBounds, NameableFigure, AnchorFigure, MultipleFigure {
	private static final int MULTIPLICITY_PANEL_OFFSET = 5;
	private static final int STEREOTYPE_PANEL_WIDTH = 30;
	private static final int STEREOTYPE_PANEL_WIDTH_OFFSET = 5;
	private static Dimension defaultSize = new Dimension(100,100);
	private static Image serviceImage;
	private static Image activeImage;
	private static Image userInitiatedImage;
	
	static {
		serviceImage = ImageHelper.createFromExecutionModelResource("icons/service24.gif");
		userInitiatedImage = ImageHelper.createFromExecutionModelResource("icons/userinitiated24.gif");
		activeImage = ImageHelper.createFromExecutionModelResource("icons/active24.gif");
	}
	
	private Label nameLabel;
	private ViewComponentBorder border;
	private Panel contentPanel;
	private Figure stereotypePanel;
	
	private Figure mainLayer;
	private Panel multiplicityLayer;
	
	
	public ViewComponentFigure() {
		
		/*
		// set up the empty border
		border= new ViewComponentBorder();
		
		// empty the border for this figure
		setBorder(null);
		
		// set up the layout manager
		FlowLayout layout = new FlowLayout(true);
		layout.setMajorSpacing(0);
		layout.setMinorSpacing(0);
		setLayoutManager(layout);
		
		//
		// set up the figure contents
		//
		
		contentPanel = new Panel();
		contentPanel.setVisible(true);
		contentPanel.setBorder(new LineBorder(ColorConstants.black));
		contentPanel.setBackgroundColor(ColorConstants.listBackground);
		contentPanel.setLayoutManager(new FixedSizeStackLayout());
		
		contentPanel.setSize(defaultSize.width-STEREOTYPE_PANEL_WIDTH, defaultSize.height);
		add(contentPanel);
		
		// set up the contents panel
		nameLabel = new Label("some label");
		nameLabel.setLocation(new Point(10,10));
		contentPanel.add(nameLabel);
		
		
		//
		// set up the stereotypes icon panel
		//
		stereotypePanel = new Panel();
		
		stereotypePanel.setVisible(true);
		stereotypePanel.setBackgroundColor(ColorConstants.listBackground);
		stereotypePanel.setBorder(null);
		stereotypePanel.setSize(STEREOTYPE_PANEL_WIDTH, defaultSize.height);
		
		FixedSizeFlowLayout stereotypesLayout = new FixedSizeFlowLayout();
		stereotypesLayout.setHorizontal(false);
		stereotypesLayout.setMajorAlignment(FlowLayout.ALIGN_RIGHTBOTTOM);
		stereotypesLayout.setMinorAlignment(FlowLayout.ALIGN_CENTER);
		stereotypePanel.setLayoutManager(stereotypesLayout);
		
		add(stereotypePanel);
		
		// set up the stereotypes panel
		updateStereotypeContents();
				
		// set up other figure properties
		setBackgroundColor(ColorConstants.listBackground);
		setOpaque(true);
		
		*/
		setLayoutManager(new FreeformLayout());
		setBorder(null); // empty the border for this figure
		
		//
		// Sublayer
		//
		
		multiplicityLayer = new Panel();
		multiplicityLayer.setVisible(true);
		multiplicityLayer.setBorder(new LineBorder(ColorConstants.black));
		
		multiplicityLayer.setLocation(new Point(MULTIPLICITY_PANEL_OFFSET,MULTIPLICITY_PANEL_OFFSET));
		multiplicityLayer.setSize(defaultSize);
		multiplicityLayer.setBackgroundColor(ColorConstants.white);
		add(multiplicityLayer);
		
		//
		// main layer
		// 
		mainLayer = new Figure();
		mainLayer.setVisible(true);
		mainLayer.setBorder(null);
		mainLayer.setOpaque(false);
		
		FlowLayout mainLayerLayout= new FlowLayout(true);
		mainLayerLayout.setMajorSpacing(0);
		mainLayerLayout.setMinorSpacing(0);
		mainLayer.setLayoutManager(mainLayerLayout);
		
		mainLayer.setSize(defaultSize);
		add(mainLayer);
		
		//
		// set up the figure contents
		//
		contentPanel = new Panel();
		contentPanel.setVisible(true);
		contentPanel.setBorder(new LineBorder(ColorConstants.black));
		contentPanel.setBackgroundColor(ColorConstants.listBackground);
		contentPanel.setLayoutManager(new FixedSizeStackLayout());
		
		contentPanel.setOpaque(false);
		
		contentPanel.setSize(defaultSize.width-STEREOTYPE_PANEL_WIDTH-STEREOTYPE_PANEL_WIDTH_OFFSET, defaultSize.height);
		mainLayer.add(contentPanel);
			
		// set up the contents panel
		nameLabel = new Label("some label");
		nameLabel.setLocation(new Point(10,10));
		contentPanel.add(nameLabel);
		
		//
		// set up the stereotypes icon panel
		//
		stereotypePanel = new Figure();
		
		stereotypePanel.setVisible(true);
		stereotypePanel.setOpaque(false);
		
		//stereotypePanel.setBackgroundColor(ColorConstants.red);
		
		stereotypePanel.setBorder(new MarginBorder(0,5	,0,0));
		stereotypePanel.setSize(STEREOTYPE_PANEL_WIDTH, defaultSize.height);
		
		
		FixedSizeFlowLayout stereotypesLayout = new FixedSizeFlowLayout();
		stereotypesLayout.setHorizontal(false);
		stereotypesLayout.setMajorAlignment(FlowLayout.ALIGN_RIGHTBOTTOM);
		stereotypesLayout.setMinorAlignment(FlowLayout.ALIGN_CENTER);
		stereotypePanel.setLayoutManager(stereotypesLayout);
		mainLayer.add(stereotypePanel);
		
		
		// set up the stereotypes panel
		updateStereotypeContents();
				
		// set up other figure properties
		//setBackgroundColor(ColorConstants.listBackground);
		setOpaque(true);
	}

	
	void updateStereotypeContents() {
		stereotypePanel.getChildren().clear();
		
		if (isPersistence()){
			stereotypePanel.add(new ImageFigure(serviceImage));
		}
		
		if (isRealTime()){
			stereotypePanel.add(new ImageFigure(activeImage));
		}
		
		if (isPresentation()){
			stereotypePanel.add(new ImageFigure(userInitiatedImage));
		}
		
		stereotypePanel.repaint();
	}

	/**
	 * @see org.eclipse.gef.handles.HandleBounds#getHandleBounds()
	 */
	public Rectangle getHandleBounds() {
		return contentPanel.getBounds().getCropped(new Insets(0,0,0,0));
	}
	
	/* (non-Javadoc)
	 * @see edu.uts.reekie.designer.conceptual.figures.AnchorBounds#getAnchorBounds()
	 */
	public IFigure getAnchorFigure() {
		return contentPanel;
	}
	

	public Dimension getPreferredSize(int w, int h) {
		Dimension prefSize = super.getPreferredSize(w, h);
		
		prefSize.union(defaultSize);
		return prefSize;
	}

	public void setBounds(Rectangle rect){
		/*
		super.setBounds(rect);
		
		// adjust the inside panels
		final int horizontalInset = 0; 
		
		Rectangle cr = new Rectangle(0,0,rect.width-STEREOTYPE_PANEL_WIDTH, rect.height);
		Rectangle sr = new Rectangle(cr.x + cr.width, 0,STEREOTYPE_PANEL_WIDTH,rect.height);
		
		contentPanel.setSize(rect.width-STEREOTYPE_PANEL_WIDTH-horizontalInset,rect.height);
		stereotypePanel.setSize(STEREOTYPE_PANEL_WIDTH,rect.height);
		*/
		
		
		Rectangle real = new Rectangle(rect.x,rect.y, rect.width,rect.height+MULTIPLICITY_PANEL_OFFSET);
		super.setBounds(real);
		
		mainLayer.setBounds(rect);
		
		contentPanel.setSize(rect.width-STEREOTYPE_PANEL_WIDTH-STEREOTYPE_PANEL_WIDTH_OFFSET,rect.height);
		stereotypePanel.setSize(STEREOTYPE_PANEL_WIDTH,rect.height);
		multiplicityLayer.setSize(contentPanel.getSize().width, contentPanel.getSize().height);
	}
	
	
	

	/**
	 * @see org.eclipse.draw2d.Figure#paintFigure(Graphics)
	 */
	protected void paintFigure(Graphics graphics) {
		
		Rectangle rect = getBounds().getCopy();
		rect.crop(new Insets(2,0,2,0));
		graphics.fillRectangle(rect);
		
	}

	/**
	 * Returns the text inside the TextFlow.
	 * 
	 * @return the text flow inside the text.
	 */
	public String getName() {
		return nameLabel.getText();
	}

	/**
	 * Sets the text of the TextFlow to the given value.
	 * 
	 * @param newText the new text value.
	 */
	public void setName(String newText) {
		nameLabel.setText(newText);
	}
	
	private boolean isRealTime = false;
	private boolean isPresentation = false;
	private boolean isPersistence = false;
	
	public boolean isRealTime() {
		return isRealTime;
	}

	public void setRealTime(boolean isRealTime) {
		this.isRealTime = isRealTime;
		updateStereotypeContents();
	}

	public boolean isPresentation() {
		return isPresentation;
	}

	public void setPresentation(boolean isPresentation) {
		this.isPresentation = isPresentation;
		updateStereotypeContents();
		
	}

	public boolean isPersistence() {
		return isPersistence;
	}

	public void setPersistence(boolean isPersistence) {
		this.isPersistence = isPersistence;
		updateStereotypeContents();
	}

	public String toString() {
		return "ViewComponentFigure"; //$NON-NLS-1$
	}

	public void validate() {
		if(isValid()) return;
		super.validate();
	}
	
private boolean isMultiple = false;
	
	public boolean isMultiple() {
		return isMultiple;
	}

	public void setMultiple(boolean isMultiple) {
		this.isMultiple= isMultiple;
		multiplicityLayer.setVisible(this.isMultiple);
		this.repaint();
		invalidate();
		
	}

	protected boolean useLocalCoordinates(){return false;}
}
